/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package nl.windesheim.archdemo.presentationmodel;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import nl.windesheim.archdemo.dao.GlobalInstances;
import nl.windesheim.archdemo.dao.OrderDao;
import nl.windesheim.archdemo.model.Customer;
import nl.windesheim.archdemo.model.Order;
import nl.windesheim.archdemo.model.OrderLine;
import nl.windesheim.archdemo.model.Product;
import nl.windesheim.archdemo.view.EditOrderDialog;
import nl.windesheim.archdemo.view.SelectCustomerDialog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

/**
 *
 * @author reindert
 */
public class EditOrderDialogPresenter implements ListSelectionListener, ActionListener {

    private OrderDao orderDao = GlobalInstances.getOrderDao();
    private EditOrderDialog view;
    private CustomerPanelPresenter customerPresenter;
    private OrderLineTablePresenter orderLineTablePresenter;
    private ProductTablePresenter productPresenter = new ProductTablePresenter();
    private List<ChangeListener> listeners;

    public ProductTablePresenter getProductViewModel() {
        return productPresenter;
    }
    private Order order;

    public EditOrderDialogPresenter(Order order) {
        this.order = order;
        this.orderLineTablePresenter = new OrderLineTablePresenter();
        this.orderLineTablePresenter.setOrder(order);

    }

    // init makes sense after view is set
    public void setView(EditOrderDialog view) {
        this.view = view;
        view.setButtonListener(this);
        // If customer viewmodel changes, the customerpanel needs to update
        this.customerPresenter = new CustomerPanelPresenter(view.getCustomerPanel());
        if (order.getCustomer() != null) {
            this.customerPresenter.setCustomer(order.getCustomer());
        }

        // we need to know when selection on product table changes
        JTable pt = view.getProductTable();
        pt.getSelectionModel().addListSelectionListener(this);
        pt.changeSelection(0, 0, false, false);
        valueChanged(new ListSelectionEvent(pt.getSelectionModel(), 0, 0, false));

        this.checkAllSet();
    }

    public OrderLineTablePresenter getOrderLineTablePresenter() {
        return orderLineTablePresenter;
    }

    /** enables ok button, but only if customer and at least 1 orderline are set. */
    private void checkAllSet() {
        if (customerPresenter.getCustomer() != null
                && order.getOrderLines() != null) {
            view.setOkEnabled();
        }
    }

    /** Called whenever a product gets selected,
    makes sure we can never set spinner higher than stock for that product */
    @Override
    public void valueChanged(ListSelectionEvent lse) {
        int sel = view.getProductTable().getSelectedRow();
        Integer maxAmount = productPresenter.getRowModel(sel).getStock();

        JSpinner spinner = view.getAmountSpinner();
        Integer value = (Integer) spinner.getValue();

        ((SpinnerNumberModel) spinner.getModel()).setMaximum(maxAmount);

        if (value > maxAmount) {
            spinner.setValue(maxAmount);
        }
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        // ok clicked: save
        if (ae.getActionCommand().equals("OK")) {
            //orderDao.save(order);
        } else if (ae.getActionCommand().equals("SelectCustomer")) {
            handleSelectCustomer();
        } else if (ae.getActionCommand().equals("addOrderLine")) {
            handleAddOrderLine();
        }
        checkAllSet();
    }

    private void handleSelectCustomer() {
        // show select customer dialog

        SelectCustomerDialog selectCustomerDialog = new SelectCustomerDialog((JFrame) view.getParent(), true, new CustomerTablePresenter());
        selectCustomerDialog.setVisible(true);
        if (selectCustomerDialog.getReturnStatus() == SelectCustomerDialog.RET_OK) {
            Customer c = selectCustomerDialog.getSelection();
            customerPresenter.setCustomer(c);
            order.setCustomer(c);
        }
        fireChange();
    }

    private void handleAddOrderLine() {
        // handle adding orderline to order
        Product p = productPresenter.getRowModel(view.getProductTable().getSelectedRow());
        if (order.getOrderLines() == null) {
            order.setOrderLines(new ArrayList<OrderLine>(1));
        }
        OrderLine ol = new OrderLine();
        ol.setProduct(p);
        ol.setAmount((Integer) view.getAmountSpinner().getValue());
        order.getOrderLines().add(ol);

        view.getOrderLineTable().updateUI();
        fireChange();
    }

    public Order getOrder() {
        return order;
    }

    public void addChangeListener(ChangeListener l) {
        if (this.listeners == null) {
            this.listeners = new ArrayList<ChangeListener>();
        }
        this.listeners.add(l);
    }

    public void fireChange() {
        if (this.listeners != null) {
            for (ChangeListener l : this.listeners) {
                l.stateChanged(new ChangeEvent(this));
            }
        }
    }
}
